<?php

namespace app\common\service\module_manage\netfilter;

use app\common\definition\InternetProtocolsDefinition;
use app\common\service\BaseService;
use think\Db;

class VirtualRule extends BaseService
{
    /**
     * @name: 列表
     * @Param: 
     * @Description: 
     * @Author: foo
     * @Date: 2019-11-05 10:38:57
     */
    public function list ($filterData)
    {
        $server = Db::name('VirtualRule')->where('host_id', $filterData['host_id']);

        isset($filterData['status']) && is_numeric($filterData['status']) ?  $server->where('status', $filterData['status']) : '' ;//状态
        isset($filterData['process']) && is_numeric($filterData['process']) ?  $server->where('process', $filterData['process']) : '' ;//处置方式
        isset($filterData['protocols']) && is_numeric($filterData['protocols']) ?  $server->where('protocols', $filterData['protocols']) : '' ;//协议
        isset($filterData['direction']) && is_numeric($filterData['direction']) ?  $server->where('direction', $filterData['direction']) : '' ;//流量方向
        isset($filterData['alias']) && !empty($filterData['alias']) ?  $server->whereLike('alias', '%' . $filterData['alias'] . '%') : '' ;//规则名

        if(isset($filterData['src_port']) && is_numeric($filterData['src_port']))//来源端口
        {
            $server->where($filterData['src_port'] . ' BETWEEN src_port_s AND src_port_e');
        }

        if(isset($filterData['dest_port']) && is_numeric($filterData['dest_port']))//来源端口
        {
            $server->where($filterData['dest_port'] . ' BETWEEN dest_port_s AND dest_port_e');
        }
         
        if(isset($filterData['src_ip']) && !empty($filterData['src_ip']))//来源端口
        {
            $sip = ip2long($filterData['src_ip']);
            if(empty($sip))
            {
                $server->whereRaw("INET_NTOA(src_ip_s) LIKE '%" . $filterData['src_ip'] . "%'" . " OR INET_NTOA(src_ip_e) LIKE '%" . $filterData['src_ip'] . "%'"  );
            }
            else
            {
                $server->where($sip . ' BETWEEN src_ip_s AND src_ip_e');
            }
        }

        if(isset($filterData['dest_ip']) && !empty($filterData['dest_ip']))//来源端口
        {
            $dip = ip2long($filterData['dest_ip']);
            if(empty($dip))
            {
                $server->whereRaw("INET_NTOA(dest_ip_s) LIKE '%" . $filterData['dest_ip'] . "%'" . " OR INET_NTOA(dest_ip_e) LIKE '%" . $filterData['dest_ip'] . "%'"  );
            }
            else
            {
                $server->where($sip . ' BETWEEN dest_ip_s AND dest_ip_e');
            }
        }

        $return = $server->group('fid')->paginate()->toArray();

        return $return;
    }

    /**
     * @name: 获取子数据
     * @Param: 
     * @Description: 
     * @Author: foo
     * @Date: 2019-11-05 17:59:10
     */
    public function childList ($host_id, $ruleId)
    {
        $return = Db::name('VirtualRule')->where('host_id', $host_id)->whereIn('fid', $ruleId)->select();

        return $return;
    }
    /**
     * @name: 第一次添加
     * @Param: 
     * @Description: 
     * @Author: foo
     * @Date: 2019-11-05 16:54:26
     */
    public function firstAdd ($insertData)
    {
        $return = Db::name('VirtualRule')->insertGetId($insertData);

        return $return;
    }

    /**
     * @name: 添加子数据
     * @Param: 
     * @Description: 
     * @Author: foo
     * @Date: 2019-11-05 16:55:33
     */
    public function childAdd ($insertData)
    {
        Db::name('VirtualRule')->insertAll($insertData);
    }

    /**
     * @name: 手动规则删除
     * @Param: 
     * @Description: 
     * @Author: foo
     * @Date: 2019-11-05 17:41:36
     */
    public function delete($host_id, $rule_id)
    {
        Db::name('VirtualRule')->where('host_id', $host_id)->whereIn('id', $rule_id)->delete();
        Db::name('VirtualRule')->where('host_id', $host_id)->whereIn('fid', $rule_id)->delete();
    }

    /**
     * @name: 添加的 第一条 规则 添加 fid
     * @Param: 
     * @Description: 
     * @Author: foo
     * @Date: 2019-11-11 14:39:17
     */
    public function firstRuleAddFid ($fid, $host_id)
    {
        Db::name('VirtualRule')->where('id', $fid)->where('host_id', $host_id)->update(['fid'=> $fid]);
    }

    /**
     * @name: 批量 添加第一条规则 的fid 用于 学习数据生成 规则 时
     * @Param: 
     * @Description: 
     * @Author: foo
     * @Date: 2019-11-11 14:43:36
     */
    public function morefirstRuleAddFid ($host_id)
    {
        Db::name('VirtualRule')->where('fid', 0)->where('host_id', $host_id)->update(['fid'=> Db::raw('id')]);
    }

    /**
     * @name: 开启规则
     * @Param: 
     * @Description: 
     * @Author: foo
     * @Date: 2019-11-12 13:59:58
     */
    public function onOff ($host_id, $rule_id, $status)
    {
        Db::name('VirtualRule')->where('host_id', $host_id)->whereIn('fid', $rule_id)->update([
            'status'=> $status
        ]);
    }

    /**
     * @name: 规则区间检测
     * @Param: 
     * @Description: 
     * @Author: foo
     * @Date: 2019-11-14 17:58:30
     */
    public function checkRule ($host_id, $data, $fid, $protocols)
    {
        $db = Model('VirtualRule')
        ->where($data['src_ip_s'] . ' BETWEEN src_ip_s AND src_ip_e OR ' . $data['src_ip_e'] . ' BETWEEN src_ip_s AND src_ip_e OR (src_ip_s > ' . $data['src_ip_s'] . ' AND src_ip_e < ' . $data['src_ip_e'] . ')' )
        ->where($data['src_port_s'] . ' BETWEEN src_port_s AND src_port_e OR ' . $data['src_port_e'] . ' BETWEEN src_port_s AND src_port_e OR (src_port_s > ' . $data['src_port_s'] . ' AND src_port_e < ' . $data['src_port_e'] . ')')
        ->where($data['dest_ip_s'] . ' BETWEEN dest_ip_s AND dest_ip_e OR ' . $data['dest_ip_e'] . ' BETWEEN dest_ip_s AND dest_ip_e  OR (dest_ip_s > ' . $data['dest_ip_s'] . ' AND dest_ip_e < ' . $data['dest_ip_e'] . ')')
        ->where($data['dest_port_s'] . ' BETWEEN dest_port_s AND dest_port_e OR ' . $data['dest_port_e'] . ' BETWEEN dest_port_s AND dest_port_e OR (dest_port_s > ' . $data['dest_port_s'] . ' AND dest_port_e < ' . $data['dest_port_e'] . ')')
        ->where('fid', '<>', $fid)
        ->where('host_id', $host_id);
        $protocols == InternetProtocolsDefinition::ALL_PROTOCOL ? : $db->where('protocols', $protocols);
        $return = $db->count();

        return $return;
    }

    /**
     * @name: 查找
     * @Param: 
     * @Description: 
     * @Author: foo
     * @Date: 2019-11-15 15:00:32
     */
    public function findOne ($id)
    {
        $return = Db::name('VirtualRule')->find($id);

        if (empty($return))
        {
            $this->setError($this->CODE_FAIL, '该条规则不存在会被删除');
            return [];
        }
        return $return;
    }
}